import base64
import os
from cryptography.fernet import Fernet
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from dotenv import load_dotenv
from passlib.context import CryptContext

# 密码哈希上下文
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")

# 加载环境变量
load_dotenv()

# 从环境变量获取密钥，如果不存在则生成一个
SECRET_KEY = os.getenv("ENCRYPTION_SECRET_KEY")
if not SECRET_KEY:
    # 生成一个随机密钥
    key = Fernet.generate_key()
    SECRET_KEY = base64.urlsafe_b64encode(key).decode('utf-8')
    # 打印密钥，便于添加到环境变量
    print(f"生成的加密密钥: {SECRET_KEY}")
    print("请将此密钥添加到.env文件中，变量名为ENCRYPTION_SECRET_KEY")

# 确保密钥是Fernet格式
try:
    key_bytes = base64.urlsafe_b64decode(SECRET_KEY)
    if len(key_bytes) != 32:
        raise ValueError("密钥长度不正确")
    fernet = Fernet(SECRET_KEY.encode('utf-8') if isinstance(SECRET_KEY, str) else SECRET_KEY)
except Exception as e:
    print(f"警告: 加密密钥格式不正确: {e}")
    # 如果密钥格式不正确，生成一个新的
    key = Fernet.generate_key()
    SECRET_KEY = key if isinstance(key, str) else key.decode('utf-8')
    fernet = Fernet(key)
    print(f"已生成新的加密密钥: {SECRET_KEY}")
    print("请将此密钥添加到.env文件中，变量名为ENCRYPTION_SECRET_KEY")

def encrypt_password(password: str) -> str:
    """
    加密密码
    
    Args:
        password: 明文密码
        
    Returns:
        加密后的密码
    """
    if not password:
        return ""
    
    # 将明文密码转为字节
    password_bytes = password.encode('utf-8')
    
    # 加密
    encrypted_bytes = fernet.encrypt(password_bytes)
    
    # 返回加密后的字符串
    return encrypted_bytes.decode('utf-8')

def decrypt_password(encrypted_password: str) -> str:
    """
    解密密码
    
    Args:
        encrypted_password: 加密后的密码
        
    Returns:
        解密后的明文密码
    """
    if not encrypted_password:
        return ""
    
    try:
        # 将加密字符串转为字节
        encrypted_bytes = encrypted_password.encode('utf-8')
        
        # 解密
        decrypted_bytes = fernet.decrypt(encrypted_bytes)
        
        # 返回解密后的字符串
        return decrypted_bytes.decode('utf-8')
    except Exception as e:
        print(f"解密错误: {e}")
        # 解密失败时直接返回原始值，这种情况通常是密码本身未加密
        return encrypted_password

# 添加密码哈希验证功能

def get_password_hash(password: str) -> str:
    """
    获取密码的哈希值
    
    Args:
        password: 明文密码
        
    Returns:
        密码哈希值
    """
    return pwd_context.hash(password)

def verify_password(plain_password: str, hashed_password: str) -> bool:
    """
    验证密码
    
    Args:
        plain_password: 明文密码
        hashed_password: 哈希密码
        
    Returns:
        密码是否匹配
    """
    return pwd_context.verify(plain_password, hashed_password)